package com.party.mobile.biz.sign;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.party.common.paging.Page;
import com.party.common.utils.DateUtils;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.sign.*;
import com.party.core.service.sign.ISignApplyService;
import com.party.core.service.sign.ISignGroupService;
import com.party.core.service.sign.ISignProjectService;
import com.party.core.service.sign.ISignRecordService;
import com.party.mobile.web.dto.sign.output.SignRecodListOutput;
import com.party.notify.notifyPush.servce.INotifySendService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 签到记录业务接口
 * Created by wei.li
 *
 * @date 2017/6/12 0012
 * @time 10:45
 */

@Service
public class SignRecordBizService {

    @Autowired
    private ISignProjectService signProjectService;

    @Autowired
    private ISignApplyService signApplyService;

    @Autowired
    private ISignRecordService signRecordService;

    @Autowired
    private ISignGroupService signGroupService;

    @Autowired
    private INotifySendService notifySendService;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 签到集合列表
     * @param applyId 报名编号
     * @return 签到集合
     */
    public List<SignRecodListOutput> list(String applyId){
        SignApply signApply = signApplyService.get(applyId);
        if (null == signApply){
            throw new BusinessException("报名信息不存在");
        }
        SignProject signProject = signProjectService.get(signApply.getProjectId());
        Date now = new Date();

        List<Date> dateList;
        //如果当前小于开始时间
        if (DateUtils.compareDate(now, signProject.getStartTime()) == -1){
            return Collections.EMPTY_LIST;
        }
        //如果当前大于结束时间
        dateList = DateUtils.getDateDifference(signProject.getStartTime(), signProject.getEndTime());

        SignRecord signRecord = new SignRecord();
        signRecord.setApplyId(applyId);
        List<SignRecord> signRecordList = signRecordService.list(signRecord);
        List<SignRecodListOutput> listOutputList = isSign(dateList, signRecordList);
        return listOutputList;
    }

    /**
     * 是否签到列表
     * @param dateList 时间列表
     * @param signRecordList 签到列表
     * @return 是否签到的列表
     */
    public List<SignRecodListOutput> isSign(List<Date> dateList, List<SignRecord> signRecordList){
        List<SignRecodListOutput> listOutputList = Lists.newArrayList();
        Date today = new Date();
        for (Date date : dateList){
            SignRecodListOutput signRecodListOutput = new SignRecodListOutput();
            signRecodListOutput.setDate(date);
            for (SignRecord signRecord : signRecordList){
                if (DateUtils.formatDate(date, "yyyy-MM-dd").equals(DateUtils.formatDate(signRecord.getCreateDate(), "yyyy-MM-dd"))){
                    signRecodListOutput.setId(signRecord.getId());
                    signRecodListOutput.setSign(true);
                    break;
                }
            }

            if (null == signRecodListOutput.getSign()){
                if (DateUtils.getDay(date) < DateUtils.getDay(today)){
                    signRecodListOutput.setSign(false);
                }
            }
            listOutputList.add(signRecodListOutput);
        }
        return listOutputList;
    }


    /**
     * 签到
     * @param signRecord 签到记录
     */
    @Transactional
    public void sign(SignRecord signRecord){

        //报名叠加
        SignApply signApply = signApplyService.get(signRecord.getApplyId());

        //验证报名时间
        SignProject signProject = signProjectService.get(signApply.getProjectId());
        Date now = new Date();
        if (DateUtils.compareDate(signProject.getStartTime(), now) == 1
                || DateUtils.compareDate(now, signProject.getEndTime()) == 1){
            throw new BusinessException("签到异常,在签到时间外");
        }
        signApply.setStepNum(signApply.getStepNum() + signRecord.getStepNum());
        signApplyService.update(signApply);

        //小组叠加
        if (!Strings.isNullOrEmpty(signApply.getGroupId())
                && SignGradeStatus.EFFECTIVE.getCode().equals(signApply.getGradeStatus())){
            SignGroup signGroup = signGroupService.get(signApply.getGroupId());
            signGroup.setStepNum(signGroup.getStepNum() + signRecord.getStepNum());
            signGroupService.update(signGroup);
        }

        //保存记录
        signRecordService.insert(signRecord);

        try {
            notifySendService.signSuccess(signApply.getProjectId(), signApply.getMemberId(), signApply.getId());
        } catch (Exception e) {
            logger.error("消息推送异常", e);
        }
    }

    /**
     * 我的运动打卡记录
     *
     * @param applyId 报名id
     * @param page    分页参数
     */
    public List<SignRecord> myRecordList(String applyId, Page page) {
        SignRecord signRecord = new SignRecord();
        signRecord.setApplyId(applyId);
        List<SignRecord> signRecords = signRecordService.listPage(signRecord, page);
        return signRecords;
    }


    /**
     * 获取项目打卡日历数据
     *
     * @param projectId 项目id
     * @param applyId   报名id
     * @param yearMonth 年-月
     * @return
     * @throws Exception
     */
    public List<SignRecodListOutput> myCalendarRecordList(String projectId, String applyId, String yearMonth) throws Exception {
        SignProject signProject = signProjectService.get(projectId);
        if (signProject == null) {
            throw new Exception("项目不存在");
        }
        Calendar newInstance = Calendar.getInstance();
        // 构造当前年份、月份的新日期
        String[] arr = yearMonth.split("-");
        newInstance.set(Calendar.YEAR, Integer.parseInt(arr[0]));
        newInstance.set(Calendar.MONTH, Integer.parseInt(arr[1]) - 1);
        newInstance.set(Calendar.DATE, 1);

        int monthLastDay = newInstance.getActualMaximum(Calendar.DAY_OF_MONTH); // 月最后一天
        newInstance.set(Calendar.DAY_OF_MONTH, 1);
        Date newStartTime = newInstance.getTime();
        newInstance.set(Calendar.DAY_OF_MONTH, monthLastDay);
        Date newEndTime = newInstance.getTime();

        // 用来比较日历中的日期是否在项目有效期内
        String formateStart = DateUtils.formatDate(signProject.getStartTime(), DateUtils.DATE_PATTERN);
        Date startTime = DateUtils.parse(formateStart, DateUtils.DATE_PATTERN);
        String formateEnd = DateUtils.formatDate(signProject.getEndTime(), DateUtils.DATE_PATTERN);
        Date endTime = DateUtils.parse(formateEnd, DateUtils.DATE_PATTERN);

        String formateCurrent = DateUtils.formatDate(new Date(), DateUtils.DATE_PATTERN);
        Date currentTime = DateUtils.parse(formateCurrent, DateUtils.DATE_PATTERN);

        List<SignRecodListOutput> monthList = Lists.newArrayList();

        // 开始日期和结束日期的中间日期
        List<Date> dateList = DateUtils.getDateDifference(newStartTime, newEndTime);
        for (Date day : dateList) {
            newInstance.setTime(day);
            int currentDay = newInstance.get(Calendar.DATE);
            // 补前面的空
            if (currentDay == 1) { // 每月1号
                int startDayOfWeek = newInstance.get(Calendar.DAY_OF_WEEK) - 1;
                for (int i = 0; i < startDayOfWeek; i++) { // 如果开始日期1号不是周日，补位默认日期
                    SignRecodListOutput output = new SignRecodListOutput();
                    output.setDay(0);
                    output.setStepNum(0L);
                    output.setValid(1); // 补位
                    output.setSign(false);
                    monthList.add(output);
                }
            }

            // 正常部分
            SignRecodListOutput calendarDay = new SignRecodListOutput();
            calendarDay.setDay(currentDay);

            String formatDate = DateUtils.formatDate(newInstance.getTime(), DateUtils.DATE_PATTERN);
            Date parseDate = DateUtils.parse(formatDate, DateUtils.DATE_PATTERN);
            if (parseDate.before(startTime) || parseDate.after(endTime)) { // 超出范围内
                calendarDay.setValid(2); // 超出范围外
            } else {
                if (parseDate.before(currentTime)) { // 已经过去的日期
                    calendarDay.setValid(4);
                } else {
                    calendarDay.setValid(3);
                }
                if (StringUtils.isEmpty(applyId)) {
                    calendarDay.setSign(false);
                    calendarDay.setStepNum(0L);
                } else {
                    SignRecord signRecord = signRecordService.getByDay(applyId, day);
                    if (signRecord != null) {
                        calendarDay.setSign(true);
                        calendarDay.setStepNum(signRecord.getStepNum());
                    } else {
                        calendarDay.setSign(false);
                        calendarDay.setStepNum(0L);
                    }
                }
            }
            monthList.add(calendarDay);

            // 补后面的空
            if (currentDay == monthLastDay) { // 每月最后一日
                int endDayOfWeek = newInstance.get(Calendar.DAY_OF_WEEK) - 1;
                for (int i = endDayOfWeek; i < 6; i++) {
                    SignRecodListOutput output = new SignRecodListOutput();
                    output.setDay(0);
                    output.setStepNum(0L);
                    output.setValid(1);
                    output.setSign(false);
                    monthList.add(output);
                }
            }
        }
        return monthList;
    }

    /**
     * 更新步数
     *
     * @param applyId 报名id
     * @param stepNum 最新步数
     */
    @Transactional
    public void updateStepNum(String applyId, Long stepNum) {
        // 更新今日步数
        SignRecord signRecord = signRecordService.getToday(applyId);

        // 更新报名人员累计步数
        SignApply signApply = signApplyService.get(applyId);
        if (signApply != null) {
            if (signRecord != null) { // 减去已有的再加新的
                signApply.setStepNum((signApply.getStepNum() - signRecord.getStepNum()) + stepNum);
            } else {
                signApply.setStepNum(signApply.getStepNum() + stepNum);
            }
            signApplyService.update(signApply);

            //小组叠加
            if (!Strings.isNullOrEmpty(signApply.getGroupId())
                    && SignGradeStatus.EFFECTIVE.getCode().equals(signApply.getGradeStatus())) {
                SignGroup signGroup = signGroupService.get(signApply.getGroupId());
                if (signRecord != null) { // 减去已有的再加新的
                    signGroup.setStepNum((signGroup.getStepNum() - signRecord.getStepNum()) + stepNum);
                } else {
                    signGroup.setStepNum(signGroup.getStepNum() + stepNum);
                }
                signGroupService.update(signGroup);
            }
        }

        if (signRecord != null) {
            signRecord.setStepNum(stepNum);
            signRecordService.update(signRecord);
        }
    }
}
